import { _decorator, tween, Tween, Vec3 } from 'cc';
import type { Ab_Tile_bA } from '../tile';
import { Ab_Drawer_bA } from './drawer';
const { ccclass, property } = _decorator;

@ccclass('Ab_DrawerStore_bA')
export class Ab_DrawerStore_bA extends Ab_Drawer_bA {

	private Ab_limit_bA = 1;

	public get Ab_residue_bA(){
		return super.Ab_residue_bA - this.Ab_limit_bA;
	}

	protected onLoad(){
		super.onLoad();
		this.Ab_capacity_bA = 7;
		//this.Ab_limit_bA = Ab_GameDC_bA.Ab_User_bA.Ab_lock_bA ? 1 : 0;
		this.Ab_limit_bA = 0;


		//let reg = Ab_DataTransfer_bA.Ab_follow_bA(Ab_GameDC_bA.Ab_User_bA, 'Ab_lock_bA', lock=>{
		//	if(lock) this.Ab_limit_bA = 1;
		//	else{
		//		Ab_DataTransfer_bA.Ab_cancel_bA(reg);
		//		this.Ab_limit_bA = 0;
		//	}
		//}, false);
	}

	protected start(){
		super.start();
	}

	protected Ab_getNext_bA(tile: Ab_Tile_bA, out?: Vec3){
		if(!this.Ab_base_height_bA){
			this.Ab_base_height_bA = -tile.Ab_getBackgroundPosition_bA(this.Ab_tile_size_bA).y;
			this.Ab_base_height_bA = abi.Ab_number_bA.Ab_fixedNum_bA(this.Ab_base_height_bA, 4);
		}
		let index = this.Ab_tile_list_bA.length;
		for(let i = this.Ab_tile_list_bA.length-1; i>=0; i--){
			if(this.Ab_tile_list_bA[i].Ab_ID_bA == tile.Ab_ID_bA){
				index = i+1;
				break;
			}
		}
		let position = this.Ab_getPostionByIndex_bA(index, out);
		return { index, position };
	}

	protected async Ab_afterPadded_bA(record: typeof this.Ab_record_list_bA[number]){
		let bucket: Map<string, Ab_Tile_bA[]> = new Map();

		this.Ab_tile_list_bA.forEach(t=>{
			let token = this.Ab_record_list_bA.find(r=>r.tile==t).token;
			if(this.Ab_adding_tile_bA.find(el=>el.token==token)) return void 0;

			let id = t.Ab_ID_bA;
			if(!bucket.has(id)) bucket.set(id, []);
			bucket.get(id).push(t);
		});

		let trash: Ab_Tile_bA[][] = [];
		bucket.forEach(ls=>ls.length>=3 ? trash.push(ls.sort((a,b)=>a.node.position.x-b.node.position.x).splice(0, 3)) : void 0);

		await this.Ab_refresh_bA();
		if(trash.length>0){
			await trash.Ab_forWait_bA(group=>this.Ab_removeOneGroupTile_bA(group));
			await this.Ab_refresh_bA();
		}

		let full = this.Ab_residue_bA<=0;

		if(full){
			for(let group = new Map<string, number>(), i = 0; i<this.Ab_tile_list_bA.length; i++){
				let id = this.Ab_tile_list_bA[i].Ab_ID_bA;
				if(!group.has(id)) group.set(id, 0);
				group.set(id, group.get(id)+1);

				if(group.get(id)>=3){
					full = false;
					break;
				}
			}
		}

		this.Ab_padded_call_list_bA.forEach(call=>call(record, full));
	}

	private Ab_removeOneGroupTile_bA(group: Ab_Tile_bA[]){
		let center_pos = group[1].node.position.clone();
		center_pos.y += this.Ab_tile_size_bA.height * 0.5;

		let duration = 0.2;
		let np = new abi.Ab_NudityPromise_bA<'end'>();
		group.forEach(tile=>{
			this.Ab_removeRecordByTile_bA(tile);

			Tween.stopAllByTarget(tile.node);

			tween(tile.node)
			.to(duration, {position: center_pos}, {easing: 'cubicOut'})
			.set({active: false})
			.call(()=>np.Ab_resolve_bA('end'))
			.start();
		});

		np.Ab_promise_bA.then(()=>{
			this.Ab_remove_call_list_bA.forEach(call=>call(group, this.Ab_uitrans_bA.convertToWorldSpaceAR(center_pos)));
		});

		return np.Ab_promise_bA;
	}

	private Ab_remove_call_list_bA: Array<(ls: Ab_Tile_bA[], pos: Vec3)=>any> = [];
	public Ab_onRemoveTiles_bA(call: (list: Ab_Tile_bA[], world_position: Vec3)=>any){
		this.Ab_remove_call_list_bA.push(call);
	}

	private Ab_padded_call_list_bA: Array<(record: typeof this.Ab_record_list_bA[number], full: boolean)=>any> = [];
	public Ab_onPadded_bA(call: (record: typeof this.Ab_record_list_bA[number])=>any){
		this.Ab_padded_call_list_bA.push(call);
	}

	public Ab_unshiftTile_bA(count: number){
		count = Math.min(count, this.Ab_tileCount_bA);

		if(count <= 0) return [];

		let list = this.Ab_tile_list_bA
		.filter(t=>{
			let token = this.Ab_record_list_bA.find(r=>r.tile==t).token;
			return !this.Ab_adding_tile_bA.find(el=>el.token==token);
		}).splice(0, count).map(t=>this.Ab_removeRecordByTile_bA(t));

		this.Ab_refresh_bA();

		return list;
	}

	public Ab_popLastRecord_bA(){
		if(this.Ab_record_list_bA.length<=0) return void 0;

		let record: typeof this.Ab_record_list_bA[number];
		let index: number;
		for(let i = this.Ab_record_list_bA.length-1; i>=0; i--){
			let token = this.Ab_record_list_bA[i].token;
			if(this.Ab_adding_tile_bA.find(el=>el.token==token)) continue;

			record = this.Ab_record_list_bA[i];
			index = i;
			break;
		}

		if(record){
			this.Ab_removeRecordByTile_bA(record.tile);
			this.Ab_refresh_bA();
		}

		return record;
	}
}

